<!DOCTYPE html>
<!-- saved from url=(0060)https://pyobjus.readthedocs.io/en/latest/core_tutorials.html -->
<html class=" js flexbox canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths" lang="en" style=""><!--<![endif]--><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  <title>Pyobjus API tutorial — Pyobjus 1.0a1 documentation</title>
  

  
  
  
  

  

  
  
    

  

  <link rel="stylesheet" href="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/theme.css" type="text/css">
  <link rel="stylesheet" href="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/pygments.css" type="text/css">
    <link rel="index" title="Index" href="https://pyobjus.readthedocs.io/en/latest/genindex.html">
    <link rel="search" title="Search" href="https://pyobjus.readthedocs.io/en/latest/search.html">
    <link rel="next" title="Foundation framework examples" href="https://pyobjus.readthedocs.io/en/latest/foundation_eg.html">
    <link rel="prev" title="How does Pyobjus work?" href="https://pyobjus.readthedocs.io/en/latest/pyobjus_internal.html"> 

  
  <script async="" src="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/analytics.js"></script><script src="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/modernizr.min.js"></script>


<!-- RTD Extra Head -->

<!-- 
Always link to the latest version, as canonical.
http://docs.readthedocs.org/en/latest/canonical.html
-->
<link rel="canonical" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html">

<link rel="stylesheet" href="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/readthedocs-doc-embed.css" type="text/css">

<script type="text/javascript" src="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/readthedocs-data.js"></script>

<!-- Add page-specific data, which must exist in the page js, not global -->
<script type="text/javascript">
READTHEDOCS_DATA['page'] = 'core_tutorials'
READTHEDOCS_DATA['source_suffix'] = '.rst'
</script>

<script type="text/javascript" src="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/readthedocs-analytics.js"></script>

<!-- end RTD <extrahead> -->
</head>

<body class="wy-body-for-nav" style="">

   
  <div class="wy-grid-for-nav">

    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search">
          

          
            <a href="https://pyobjus.readthedocs.io/en/latest/index.html" class="icon icon-home"> Pyobjus
          

          
          </a>

          
            
            
            
              <div class="version">
                latest
              </div>
            
          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="https://pyobjus.readthedocs.io/en/latest/search.html" method="get">
    <input type="text" name="q" placeholder="Search docs">
    <input type="hidden" name="check_keywords" value="yes">
    <input type="hidden" name="area" value="default">
  </form>
</div>

          
        </div>

        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/installation.html">Installation</a></li>
<li class="toctree-l1"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/pyobjus_internal.html">How does Pyobjus work?</a></li>
<li class="toctree-l1 current"><a class="reference internal current" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#"><span class="toctree-expand"></span>Pyobjus API tutorial</a><ul>
<li class="toctree-l2"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-dylib-manager"><span class="toctree-expand"></span>Using dylib_manager</a><ul>
<li class="toctree-l3"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#make-dylib-and-load-dylib-functions">make_dylib and load_dylib functions</a></li>
<li class="toctree-l3"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#load-framework-function">load_framework function</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-struct-types">Using struct types</a></li>
<li class="toctree-l2"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#dealing-with-pointers"><span class="toctree-expand"></span>Dealing with pointers</a><ul>
<li class="toctree-l3"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#passing-pointers">Passing pointers</a></li>
<li class="toctree-l3"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#dereferencing-pointers">Dereferencing pointers</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#objective-c-pyobjus-literals">Objective C &lt;-&gt; pyobjus literals</a></li>
<li class="toctree-l2"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#unknown-types">Unknown types</a></li>
<li class="toctree-l2"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-class">Using class</a></li>
<li class="toctree-l2"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-selector">Using @selector</a></li>
<li class="toctree-l2"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-protocol">Using @protocol</a></li>
<li class="toctree-l2"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-enum-types">Using enum types</a></li>
<li class="toctree-l2"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-vararg-methods">Using vararg methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-c-array">Using C array</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/foundation_eg.html">Foundation framework examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/pyobjus_ios.html">Pyobjus on iOS</a></li>
<li class="toctree-l1"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="https://pyobjus.readthedocs.io/en/latest/remarks.html">Remarks</a></li>
</ul>

            
          
        </div>
      <div id="rtd-p6fgh1vg" class="ethical-rtd ethical-dark-theme"><div class="ethical-sidebar"><div class="ethical-content"><a href="https://readthedocs.org/sustainability/click/472/fCXDgA8QiylM/" rel="nofollow" target="_blank" class="ethical-image-link"><img src="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/house-hiredevs-03.png"></a><div class="ethical-text"><a href="https://readthedocs.org/sustainability/click/472/fCXDgA8QiylM/" rel="nofollow" target="_blank">Hiring Python devs?<br>
Read the Docs can help!</a></div></div><div class="ethical-callout"><small><em><a href="https://readthedocs.org/sustainability/advertising/">Sponsored</a><span> · </span><a href="https://docs.readthedocs.io/en/latest/ethical-advertising.html">Ads served ethically</a></em></small></div></div><img src="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/saved_resource" style="display: none;"></div></div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="https://pyobjus.readthedocs.io/en/latest/index.html">Pyobjus</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="wy-breadcrumbs">
    
      <li><a href="https://pyobjus.readthedocs.io/en/latest/index.html">Docs</a> »</li>
        
      <li>Pyobjus API tutorial</li>
    
    
      <li class="wy-breadcrumbs-aside">
        
            
            
              <a href="https://github.com/kivy/pyobjus/blob/master/docs/source/core_tutorials.rst" class="fa fa-github"> Edit on GitHub</a>
            
          
        
      </li>
    
  </ul>

  
  <hr>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
  <div class="section" id="pyobjus-api-tutorial">
<span id="core-tutorials"></span><h1>Pyobjus API tutorial<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#pyobjus-api-tutorial" title="Permalink to this headline">¶</a></h1>
<p>This part of documentation covers tutorials related to API of pyobjus</p>
<div class="section" id="using-dylib-manager">
<h2>Using dylib_manager<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-dylib-manager" title="Permalink to this headline">¶</a></h2>
<p>You need to load code into pyobjus so it can actually find the appropriate
class with the autoclass function.</p>
<p>Maybe you want to write some Objective C code, and you want to load it into
pyobjus, or you want to use some exising <cite>.dylib</cite> or sommething similar.</p>
<p>These problems can be solved using the pyobjus dylib_manager. Currently it has
a few functions, so let’s see what we can do with them.</p>
<div class="section" id="make-dylib-and-load-dylib-functions">
<h3>make_dylib and load_dylib functions<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#make-dylib-and-load-dylib-functions" title="Permalink to this headline">¶</a></h3>
<p>For the first example, let’s say that we want to write our class in Objective
C, and after that we want to load that class into pyobjus. Okay, let’s write
a class:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#import &lt;Foundation/Foundation.h&gt;</span>

<span class="nd">@interface</span> <span class="n">ObjcClass</span> <span class="p">:</span> <span class="n">NSObject</span> <span class="p">{</span>
<span class="p">}</span>
<span class="o">-</span> <span class="p">(</span><span class="n">void</span><span class="p">)</span> <span class="n">printFromObjectiveC</span><span class="p">;</span>
<span class="nd">@end</span>

<span class="nd">@implementation</span> <span class="n">ObjcClass</span>

<span class="o">-</span> <span class="p">(</span><span class="n">void</span><span class="p">)</span> <span class="n">printFromObjectiveC</span> <span class="p">{</span>
        <span class="n">printf</span><span class="p">(</span><span class="s2">"Hello from Objective C</span><span class="se">\n</span><span class="s2">"</span><span class="p">);</span>
<span class="p">}</span>

<span class="nd">@end</span>
</pre></div>
</div>
<p>The next step is to make a .dylib for this class, and load that .dylib into
pyobjus. Suppose that we have previously saved this code into an <cite>objc_lib.m</cite>
file.</p>
<p>With pyobjus you can compile <cite>objc_lib.m</cite> into <cite>objc_lib.dylib</cite> in the
following way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make_dylib</span><span class="p">(</span><span class="s1">'objc_lib.m'</span><span class="p">,</span> <span class="n">frameworks</span><span class="o">=</span><span class="p">[</span><span class="s1">'Foundation'</span><span class="p">],</span> <span class="n">options</span><span class="o">=</span><span class="p">[</span><span class="s1">'-current_version'</span><span class="p">,</span> <span class="s1">'1.0'</span><span class="p">])</span>
</pre></div>
</div>
<p>Here, we are asking pyobjus to link <cite>objc_lib.m</cite> with the Foundation framework,
and that we want to set the <cite>-current_version</cite> option to <cite>1.0</cite>. You can also
specify others frameworks and options if you want by just adding these
elements to array.</p>
<p>The previous command will create an <cite>objc_lib.dylib</cite> file in the same directory
as the <cite>objc_lib.m</cite> file. If you want to save it to another directory
or with a different name, you can call <cite>make_dylib</cite> in this way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make_dylib</span><span class="p">(</span><span class="s1">'objc_lib.m'</span><span class="p">,</span> <span class="n">frameworks</span><span class="o">=</span><span class="p">[</span><span class="s1">'Foundation'</span><span class="p">],</span> <span class="n">out</span><span class="o">=</span><span class="s1">'/path/to/dylib/dylib_name.dylib'</span><span class="p">)</span>
</pre></div>
</div>
<p>After you make a .dylib with make_dylib function, you can load the code from
the .dylib into pyobjus on following way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">load_dylib</span><span class="p">(</span><span class="s1">'objc_lib.dylib'</span><span class="p">)</span>

<span class="c1"># or if you specified anothed loation and name for .dylib</span>
<span class="c1"># load_dylib('/path/to/dylib/dylib_name.dylib')</span>
</pre></div>
</div>
<p>Great, we have created a .dylib, loaded it into pyobjus and can now use the
ObjcClass from our <cite>objc_lib.m</cite> file:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ObjcClass</span> <span class="o">=</span> <span class="n">autoclass</span><span class="p">(</span><span class="s1">'ObjcClass'</span><span class="p">)</span>
<span class="n">o_instance</span> <span class="o">=</span> <span class="n">ObjcClass</span><span class="o">.</span><span class="n">alloc</span><span class="p">()</span><span class="o">.</span><span class="n">init</span><span class="p">()</span>
<span class="n">o_instance</span><span class="o">.</span><span class="n">printFromObjectiveC</span><span class="p">()</span>
</pre></div>
</div>
<p>This will output with:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Hello</span> <span class="kn">from</span> <span class="nn">Objective</span> <span class="n">C</span>
</pre></div>
</div>
</div>
<div class="section" id="load-framework-function">
<h3>load_framework function<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#load-framework-function" title="Permalink to this headline">¶</a></h3>
<p>There often can be situations when you need to load classes into pyobjus which
don’t belong to the Foundation framework. For example, say you want to load a
class from the AppKit framework.</p>
<p>In these cases you can use the load_framework function of dylib_manager.</p>
<p>So let’s see one simple example of using this function:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pyobjus.dylib_manager</span> <span class="k">import</span> <span class="n">load_framework</span><span class="p">,</span> <span class="n">INCLUDE</span>
<span class="n">load_framework</span><span class="p">(</span><span class="n">INCLUDE</span><span class="o">.</span><span class="n">AppKit</span><span class="p">)</span>
</pre></div>
</div>
<p>You may wonder what INCLUDE is, and can we load all Frameworks in this way?
So INCLUDE is an enum, which contains paths to various Frameworks. Currently,
INCLUDE contains paths to the following frameworks:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Accelerate</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Accelerate.framework'</span><span class="p">,</span>
<span class="n">Accounts</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Accounts.framework'</span><span class="p">,</span>
<span class="n">AddressBook</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/AddressBook.framework'</span><span class="p">,</span>
<span class="n">AGL</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/AGL.framework'</span><span class="p">,</span>
<span class="n">AppKit</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/AppKit.framework'</span><span class="p">,</span>
<span class="n">AppKitScripting</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/AppKitScripting.framework'</span><span class="p">,</span>
<span class="n">AppleScriptKit</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/AppleScriptKit.framework'</span><span class="p">,</span>
<span class="n">AppleScriptObjC</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/AppleScriptObjC.framework'</span><span class="p">,</span>
<span class="n">AppleShareClientCore</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/AppleShareClientCore.framework'</span><span class="p">,</span>
<span class="n">AppleTalk</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/AppleTalk.framework'</span><span class="p">,</span>
<span class="n">ApplicationServices</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/ApplicationServices.framework'</span><span class="p">,</span>
<span class="n">AudioToolbox</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/AudioToolbox.framework'</span><span class="p">,</span>
<span class="n">AudioUnit</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/AudioUnit.framework'</span><span class="p">,</span>
<span class="n">AudioVideoBridging</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/AudioVideoBridging.framework'</span><span class="p">,</span>
<span class="n">Automator</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Automator.framework'</span><span class="p">,</span>
<span class="n">AVFoundation</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/AVFoundation.framework'</span><span class="p">,</span>
<span class="n">CalendarStore</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CalendarStore.framework'</span><span class="p">,</span>
<span class="n">Carbon</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Carbon.framework'</span><span class="p">,</span>
<span class="n">CFNetwork</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CFNetwork.framework'</span><span class="p">,</span>
<span class="n">Cocoa</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Cocoa.framework'</span><span class="p">,</span>
<span class="n">Collaboration</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Collaboration.framework'</span><span class="p">,</span>
<span class="n">CoreAudio</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreAudio.framework'</span><span class="p">,</span>
<span class="n">CoreAudioKit</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreAudioKit.framework'</span><span class="p">,</span>
<span class="n">CoreData</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreData.framework'</span><span class="p">,</span>
<span class="n">CoreFoundation</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreFoundation.framework'</span><span class="p">,</span>
<span class="n">CoreGraphics</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreGraphics.framework'</span><span class="p">,</span>
<span class="n">CoreLocation</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreLocation.framework'</span><span class="p">,</span>
<span class="n">CoreMedia</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreMedia.framework'</span><span class="p">,</span>
<span class="n">CoreMediaIO</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreMediaIO.framework'</span><span class="p">,</span>
<span class="n">CoreMIDI</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreMIDI.framework'</span><span class="p">,</span>
<span class="n">CoreMIDIServer</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreMIDIServer.framework'</span><span class="p">,</span>
<span class="n">CoreServices</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreServices.framework'</span><span class="p">,</span>
<span class="n">CoreText</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreText.framework'</span><span class="p">,</span>
<span class="n">CoreVideo</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreVideo.framework'</span><span class="p">,</span>
<span class="n">CoreWiFi</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreWiFi.framework'</span><span class="p">,</span>
<span class="n">CoreWLAN</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/CoreWLAN.framework'</span><span class="p">,</span>
<span class="n">DirectoryService</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/DirectoryService.framework'</span><span class="p">,</span>
<span class="n">DiscRecording</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/DiscRecording.framework'</span><span class="p">,</span>
<span class="n">DiscRecordingUI</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/DiscRecordingUI.framework'</span><span class="p">,</span>
<span class="n">DiskArbitration</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/DiskArbitration.framework'</span><span class="p">,</span>
<span class="n">DrawSprocket</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/DrawSprocket.framework'</span><span class="p">,</span>
<span class="n">DVComponentGlue</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/DVComponentGlue.framework'</span><span class="p">,</span>
<span class="n">DVDPlayback</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/DVDPlayback.framework'</span><span class="p">,</span>
<span class="n">EventKit</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/EventKit.framework'</span><span class="p">,</span>
<span class="n">ExceptionHandling</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/ExceptionHandling.framework'</span><span class="p">,</span>
<span class="n">ForceFeedback</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/ForceFeedback.framework'</span><span class="p">,</span>
<span class="n">Foundation</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Foundation.framework'</span><span class="p">,</span>
<span class="n">FWAUserLib</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/FWAUserLib.framework'</span><span class="p">,</span>
<span class="n">GameKit</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/GameKit.framework'</span><span class="p">,</span>
<span class="n">GLKit</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/GLKit.framework'</span><span class="p">,</span>
<span class="n">GLUT</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/GLUT.framework'</span><span class="p">,</span>
<span class="n">GSS</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/GSS.framework'</span><span class="p">,</span>
<span class="n">ICADevices</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/ICADevices.framework'</span><span class="p">,</span>
<span class="n">ImageCaptureCore</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/ImageCaptureCore.framework'</span><span class="p">,</span>
<span class="n">ImageIO</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/ImageIO.framework'</span><span class="p">,</span>
<span class="n">IMServicePlugIn</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/IMServicePlugIn.framework'</span><span class="p">,</span>
<span class="n">InputMethodKit</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/InputMethodKit.framework'</span><span class="p">,</span>
<span class="n">InstallerPlugins</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/InstallerPlugins.framework'</span><span class="p">,</span>
<span class="n">InstantMessage</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/InstantMessage.framework'</span><span class="p">,</span>
<span class="n">IOBluetooth</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/IOBluetooth.framework'</span><span class="p">,</span>
<span class="n">IOBluetoothUI</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/IOBluetoothUI.framework'</span><span class="p">,</span>
<span class="n">IOKit</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/IOKit.framework'</span><span class="p">,</span>
<span class="n">IOSurface</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/IOSurface.framework'</span><span class="p">,</span>
<span class="n">JavaFrameEmbedding</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/JavaFrameEmbedding.framework'</span><span class="p">,</span>
<span class="n">JavaScriptCore</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/JavaScriptCore.framework'</span><span class="p">,</span>
<span class="n">JavaVM</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/JavaVM.framework'</span><span class="p">,</span>
<span class="n">Kerberos</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Kerberos.framework'</span><span class="p">,</span>
<span class="n">Kernel</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Kernel.framework'</span><span class="p">,</span>
<span class="n">LatentSemanticMapping</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/LatentSemanticMapping.framework'</span><span class="p">,</span>
<span class="n">LDAP</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/LDAP.framework'</span><span class="p">,</span>
<span class="n">MediaToolbox</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/MediaToolbox.framework'</span><span class="p">,</span>
<span class="n">Message</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Message.framework'</span><span class="p">,</span>
<span class="n">NetFS</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/NetFS.framework'</span><span class="p">,</span>
<span class="n">OpenAL</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/OpenAL.framework'</span><span class="p">,</span>
<span class="n">OpenCL</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/OpenCL.framework'</span><span class="p">,</span>
<span class="n">OpenDirectory</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/OpenDirectory.framework'</span><span class="p">,</span>
<span class="n">OpenGL</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/OpenGL.framework'</span><span class="p">,</span>
<span class="n">OSAKit</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/OSAKit.framework'</span><span class="p">,</span>
<span class="n">PCSC</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/PCSC.framework'</span><span class="p">,</span>
<span class="n">PreferencePanes</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/PreferencePanes.framework'</span><span class="p">,</span>
<span class="n">PubSub</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/PubSub.framework'</span><span class="p">,</span>
<span class="n">Python</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Python.framework'</span><span class="p">,</span>
<span class="n">QTKit</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/QTKit.framework'</span><span class="p">,</span>
<span class="n">Quartz</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Quartz.framework'</span><span class="p">,</span>
<span class="n">QuartzCore</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/QuartzCore.framework'</span><span class="p">,</span>
<span class="n">QuickLook</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/QuickLook.framework'</span><span class="p">,</span>
<span class="n">QuickTime</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/QuickTime.framework'</span><span class="p">,</span>
<span class="n">Ruby</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Ruby.framework'</span><span class="p">,</span>
<span class="n">RubyCocoa</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/RubyCocoa.framework'</span><span class="p">,</span>
<span class="n">SceneKit</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/SceneKit.framework'</span><span class="p">,</span>
<span class="n">ScreenSaver</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/ScreenSaver.framework'</span><span class="p">,</span>
<span class="n">Scripting</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Scripting.framework'</span><span class="p">,</span>
<span class="n">ScriptingBridge</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/ScriptingBridge.framework'</span><span class="p">,</span>
<span class="n">Security</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Security.framework'</span><span class="p">,</span>
<span class="n">SecurityFoundation</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/SecurityFoundation.framework'</span><span class="p">,</span>
<span class="n">SecurityInterface</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/SecurityInterface.framework'</span><span class="p">,</span>
<span class="n">ServerNotification</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/ServerNotification.framework'</span><span class="p">,</span>
<span class="n">ServiceManagement</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/ServiceManagement.framework'</span><span class="p">,</span>
<span class="n">Social</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Social.framework'</span><span class="p">,</span>
<span class="n">StoreKit</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/StoreKit.framework'</span><span class="p">,</span>
<span class="n">SyncServices</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/SyncServices.framework'</span><span class="p">,</span>
<span class="n">System</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/System.framework'</span><span class="p">,</span>
<span class="n">SystemConfiguration</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/SystemConfiguration.framework'</span><span class="p">,</span>
<span class="n">Tcl</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Tcl.framework'</span><span class="p">,</span>
<span class="n">Tk</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/Tk.framework'</span><span class="p">,</span>
<span class="n">TWAIN</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/TWAIN.framework'</span><span class="p">,</span>
<span class="n">vecLib</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/vecLib.framework'</span><span class="p">,</span>
<span class="n">VideoDecodeAcceleration</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/VideoDecodeAcceleration.framework'</span><span class="p">,</span>
<span class="n">VideoToolbox</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/VideoToolbox.framework'</span><span class="p">,</span>
<span class="n">WebKit</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/WebKit.framework'</span><span class="p">,</span>
<span class="n">XgridFoundation</span> <span class="o">=</span> <span class="s1">'/System/Library/Frameworks/XgridFoundation.framework'</span>
</pre></div>
</div>
<p>If the Framework path which you want to load isn’t present in the INCLUDE enum,
you can specify it manually. Let’s say that the path to AppKit isn’t available
via the INCLUDE enum. You could load the Framework in the following way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">load_framework</span><span class="p">(</span><span class="s1">'/System/Library/Frameworks/AppKit.framework'</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="using-struct-types">
<h2>Using struct types<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-struct-types" title="Permalink to this headline">¶</a></h2>
<p>Pyobjus currently support <code class="docutils literal notranslate"><span class="pre">NSRange</span></code>, <code class="docutils literal notranslate"><span class="pre">NSPoint</span></code>, <code class="docutils literal notranslate"><span class="pre">NSSize</span></code> and <code class="docutils literal notranslate"><span class="pre">NSRect</span></code>
structures. They are defined via the <code class="docutils literal notranslate"><span class="pre">ctypes.Structure</span></code> type.</p>
<p>Consider the following. You have an Objective C class with the name ObjcClass
and a useRange: method of that class which is defined in this way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span> <span class="p">(</span><span class="n">void</span><span class="p">)</span> <span class="n">useRange</span><span class="p">:(</span><span class="n">NSRange</span><span class="p">)</span><span class="n">r</span> <span class="p">{</span>
    <span class="n">printf</span><span class="p">(</span><span class="s2">"location: </span><span class="si">%ld</span><span class="s2">, length: </span><span class="si">%ld</span><span class="se">\n</span><span class="s2">"</span><span class="p">,</span> <span class="n">r</span><span class="o">.</span><span class="n">location</span><span class="p">,</span> <span class="n">r</span><span class="o">.</span><span class="n">length</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>So, if you want to call this method from Python, you can do something like
this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pyobjus.objc_py_types</span> <span class="k">import</span> <span class="n">NSRange</span>
<span class="kn">from</span> <span class="nn">pyobjus</span> <span class="k">import</span> <span class="n">autoclass</span>

<span class="n">ObjcClass</span> <span class="o">=</span> <span class="n">autoclass</span><span class="p">(</span><span class="s1">'ObjcClass'</span><span class="p">)</span>
<span class="n">o_cls</span> <span class="o">=</span> <span class="n">ObjcClass</span><span class="o">.</span><span class="n">alloc</span><span class="p">()</span><span class="o">.</span><span class="n">init</span><span class="p">()</span>
<span class="nb">range</span> <span class="o">=</span> <span class="n">NSRange</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span>
<span class="n">o_cls</span><span class="o">.</span><span class="n">useRange_</span><span class="p">(</span><span class="nb">range</span><span class="p">)</span>
</pre></div>
</div>
<p>This will output:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">location</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span> <span class="n">length</span><span class="p">:</span> <span class="mi">20</span>
</pre></div>
</div>
<p>A simmilar situation occurs when returning and using Objective C structure
types. Let’s say that our ObjcClass has another method with the name
makeRange:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span> <span class="p">(</span><span class="n">NSRange</span><span class="p">)</span> <span class="n">makeRange</span> <span class="p">{</span>
    <span class="n">NSRange</span> <span class="nb">range</span><span class="p">;</span>
    <span class="nb">range</span><span class="o">.</span><span class="n">length</span> <span class="o">=</span> <span class="mi">123</span><span class="p">;</span>
    <span class="nb">range</span><span class="o">.</span><span class="n">location</span> <span class="o">=</span> <span class="mi">456</span><span class="p">;</span>
    <span class="k">return</span> <span class="nb">range</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Using this method from Python is really simple. Let’s say that we have included
it from the previous Python code example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">range</span> <span class="o">=</span> <span class="n">o_cls</span><span class="o">.</span><span class="n">makeRange</span><span class="p">()</span>
<span class="nb">print</span> <span class="nb">range</span><span class="o">.</span><span class="n">length</span>
<span class="nb">print</span> <span class="nb">range</span><span class="o">.</span><span class="n">location</span>
</pre></div>
</div>
<p>And this will output:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="mi">123</span>
<span class="gp">&gt;&gt;&gt; </span><span class="mi">456</span>
</pre></div>
</div>
<p>As you can see, dealing with Objective C structs from pyobjus is simple.</p>
<p>Let’s see how to create a <code class="docutils literal notranslate"><span class="pre">NSRect</span></code> type:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">point</span> <span class="o">=</span> <span class="n">NSPoint</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span> <span class="mi">50</span><span class="p">)</span>
<span class="n">size</span> <span class="o">=</span> <span class="n">NSSize</span><span class="p">(</span><span class="mi">60</span><span class="p">,</span> <span class="mi">70</span><span class="p">)</span>
<span class="n">rect</span> <span class="o">=</span> <span class="n">NSRect</span><span class="p">(</span><span class="n">point</span><span class="p">,</span> <span class="n">size</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="dealing-with-pointers">
<h2>Dealing with pointers<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#dealing-with-pointers" title="Permalink to this headline">¶</a></h2>
<p>As you know, C has a very powerful feature with name pointers. Objective C is
a superset of the C language, so Objective C also has this great feature.</p>
<p>But wait, we are using Python, so how we can deal with pointers from Python???</p>
<div class="section" id="passing-pointers">
<h3>Passing pointers<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#passing-pointers" title="Permalink to this headline">¶</a></h3>
<p>Relax, pyobjus is doing that job for you. I think the best way to explain is to
show some concrete examples of that. So, let’s expand our ObjcClass class with
another method:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span> <span class="p">(</span><span class="n">void</span><span class="p">)</span> <span class="n">useRangePtr</span><span class="p">:(</span><span class="n">NSRange</span><span class="o">*</span><span class="p">)</span><span class="n">r_p</span> <span class="p">{</span>
    <span class="n">NSRange</span> <span class="n">r</span> <span class="o">=</span> <span class="n">r_p</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
    <span class="n">printf</span><span class="p">(</span><span class="s2">"location: </span><span class="si">%ld</span><span class="s2">, length: </span><span class="si">%ld</span><span class="se">\n</span><span class="s2">"</span><span class="p">,</span> <span class="n">r</span><span class="o">.</span><span class="n">location</span><span class="p">,</span> <span class="n">r</span><span class="o">.</span><span class="n">length</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>In previous examples you have seen how to create an <code class="docutils literal notranslate"><span class="pre">NSRange</span></code> from Python,
and you have sent values of the <code class="docutils literal notranslate"><span class="pre">NSRange</span></code> type. But now we have a situation
when the method accepts a pointer to that type.</p>
<p>With pyobjus, you can call a method in the following way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">range</span> <span class="o">=</span> <span class="n">NSRange</span><span class="p">(</span><span class="mi">40</span><span class="p">,</span> <span class="mi">80</span><span class="p">)</span>
<span class="n">o_cls</span><span class="o">.</span><span class="n">useRangePtr_</span><span class="p">(</span><span class="nb">range</span><span class="p">)</span>
</pre></div>
</div>
<p>And this will output:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">location</span><span class="p">:</span><span class="mi">40</span><span class="p">,</span> <span class="n">length</span><span class="p">:</span> <span class="mi">80</span>
</pre></div>
</div>
<p>So what has happened here? We pass the argument in the same way as with
the <code class="docutils literal notranslate"><span class="pre">useRange:</span></code> method.</p>
<p>Pyobjus knows if a method accepts pointers to a type, or accepts values of that
type. If a method accepts a pointer to a type, pyobjus will make a pointer to
that type, point it to your type and pass that pointer to the method for you.
So with this, you don’t need to care whether argument types are pointers or
values.</p>
<p>You can also return pointers to types from Objective C methods. Let’s add
another method to ObjcClass:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span> <span class="p">(</span><span class="n">NSRange</span><span class="o">*</span><span class="p">)</span> <span class="n">makeRangePtr</span> <span class="p">{</span>
    <span class="n">NSRange</span> <span class="o">*</span><span class="n">r_p</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="n">sizeof</span><span class="p">(</span><span class="n">NSRange</span><span class="p">));</span>
    <span class="n">NSRange</span> <span class="n">r</span><span class="p">;</span>
    <span class="n">r</span><span class="o">.</span><span class="n">length</span> <span class="o">=</span> <span class="mi">123</span><span class="p">;</span>
    <span class="n">r</span><span class="o">.</span><span class="n">location</span> <span class="o">=</span> <span class="mi">567</span><span class="p">;</span>
    <span class="o">*</span><span class="n">r_p</span> <span class="o">=</span> <span class="n">r</span><span class="p">;</span>
    <span class="k">return</span> <span class="n">r_p</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>As you can see, this method creates a <code class="docutils literal notranslate"><span class="pre">NSRange</span></code> pointer, assigns a value to
it, and at the end, it returns a pointer to the user. From Python, you can
consume this method in this way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">range_ptr</span> <span class="o">=</span> <span class="n">o_cls</span><span class="o">.</span><span class="n">makeRangePtr</span><span class="p">()</span>
<span class="c1"># let we see actual type of returned object</span>
<span class="nb">print</span> <span class="n">range_ptr</span>
</pre></div>
</div>
<p>This will output following:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="o">&lt;</span><span class="n">pyobjus</span><span class="o">.</span><span class="n">ObjcReferenceToType</span> <span class="nb">object</span> <span class="n">at</span> <span class="mh">0x10f34bcb0</span><span class="o">&gt;</span>
</pre></div>
</div>
<p>So here we can see another type -&gt; ObjcReferenceToType. When we have a method
which returns a pointer to some type, pyobjus will wrap that pointer with an
ObjcReferenceToType object. This object contains the actual address of the C
pointer. We can now pass that type to a function which accepts pointers.</p>
<p>Example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># note that range_ptr is of ObjcReferenceToType type</span>
<span class="n">o_cls</span><span class="o">.</span><span class="n">useRangePtr_</span><span class="p">(</span><span class="n">range_ptr</span><span class="p">)</span>
</pre></div>
</div>
<p>But you may now wonder how to dereference the pointer to get the actual value?</p>
<p>The answer is….by using the dereference function.</p>
</div>
<div class="section" id="dereferencing-pointers">
<h3>Dereferencing pointers<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#dereferencing-pointers" title="Permalink to this headline">¶</a></h3>
<p>To dereference a pointer we use the dereference function:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pyobjus</span> <span class="k">import</span> <span class="n">dereference</span>
</pre></div>
</div>
<p>If a function returns a pointer to some known type, in other words, the return
type isn’t void*, you can use the dereference function in this way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">range_ptr</span> <span class="o">=</span> <span class="n">o_cls</span><span class="o">.</span><span class="n">makeRangePtr</span><span class="p">()</span>
<span class="nb">range</span> <span class="o">=</span> <span class="n">dereference</span><span class="p">(</span><span class="n">range_ptr</span><span class="p">)</span>
</pre></div>
</div>
<p>Pyobjus will extract the return type from the method signature, and will thus
know which type to convert the pointer value to. If it returns a void pointer,
you will need to specify the type which you want pyobjus to convert the actual
value to.</p>
<p>Consider adding this method:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span> <span class="p">(</span><span class="n">void</span><span class="o">*</span><span class="p">)</span> <span class="n">makeIntVoidPtr</span> <span class="p">{</span>
    <span class="nb">int</span> <span class="o">*</span><span class="n">a</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="n">sizeof</span><span class="p">(</span><span class="nb">int</span><span class="p">));</span>
    <span class="o">*</span><span class="n">a</span> <span class="o">=</span> <span class="mi">12345</span><span class="p">;</span>
    <span class="k">return</span> <span class="p">(</span><span class="n">void</span><span class="o">*</span><span class="p">)</span><span class="n">a</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Now we can retrieve the value and dereference it:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">int_ptr</span> <span class="o">=</span> <span class="n">o_cls</span><span class="o">.</span><span class="n">makeIntVoidPtr</span><span class="p">()</span>
<span class="n">int_val</span> <span class="o">=</span> <span class="n">dereference</span><span class="p">(</span><span class="n">int_ptr</span><span class="p">,</span> <span class="n">of_type</span><span class="o">=</span><span class="n">ObjcInt</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">int_val</span>
</pre></div>
</div>
<p>This will output with:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="mi">12345</span>
</pre></div>
</div>
<p>Notice that you can specify the <code class="docutils literal notranslate"><span class="pre">of_type</span></code> optional argument even though
the method returns a <code class="docutils literal notranslate"><span class="pre">NSRange</span></code> pointer. With this, you can be sure that
pyobjus will convert the value to that type.</p>
<p>Here is the list of possible types:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'ObjcChar'</span><span class="p">,</span>
<span class="s1">'ObjcInt'</span><span class="p">,</span>
<span class="s1">'ObjcShort'</span><span class="p">,</span>
<span class="s1">'ObjcLong'</span><span class="p">,</span>
<span class="s1">'ObjcLongLong'</span><span class="p">,</span>
<span class="s1">'ObjcUChar'</span><span class="p">,</span>
<span class="s1">'ObjcUInt'</span><span class="p">,</span>
<span class="s1">'ObjcUShort'</span><span class="p">,</span>
<span class="s1">'ObjcULong'</span><span class="p">,</span>
<span class="s1">'ObjcULongLong'</span><span class="p">,</span>
<span class="s1">'ObjcFloat'</span><span class="p">,</span>
<span class="s1">'ObjcDouble'</span><span class="p">,</span>
<span class="s1">'ObjcBool'</span><span class="p">,</span>
<span class="s1">'ObjcBOOL'</span><span class="p">,</span>
<span class="s1">'ObjcVoid'</span><span class="p">,</span>
<span class="s1">'ObjcString'</span><span class="p">,</span>
<span class="s1">'ObjcClassInstance'</span><span class="p">,</span>
<span class="s1">'ObjcClass'</span><span class="p">,</span>
<span class="s1">'ObjcSelector'</span><span class="p">,</span>
<span class="s1">'ObjcMethod'</span>
</pre></div>
</div>
<p>Those already listed types are defined inside the pyobjus module, so you can
import them in the following way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pyobjus</span> <span class="k">import</span> <span class="n">ObjcChar</span><span class="p">,</span> <span class="n">ObjcInt</span> <span class="c1"># etc...</span>
</pre></div>
</div>
<p>Inside the <code class="docutils literal notranslate"><span class="pre">pyobjus.objc_py_types</span></code> module we define the struct and union
types. Here is a list of them:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'NSRange'</span><span class="p">,</span>
<span class="s1">'NSPoint'</span><span class="p">,</span>
<span class="s1">'NSRect'</span><span class="p">,</span>
<span class="s1">'NSSize'</span>
</pre></div>
</div>
<p>You can import them with:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pyobjus.objc_py_types</span> <span class="k">import</span> <span class="n">NSRange</span> <span class="c1"># etc...</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="objective-c-pyobjus-literals">
<h2>Objective C &lt;-&gt; pyobjus literals<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#objective-c-pyobjus-literals" title="Permalink to this headline">¶</a></h2>
<p>If you are familiar with Objective C literals, then you know that they
are a great feature, because literals reduce the amount of code you write.
You may wonder is there some equvivalent with pyobjus. The answer is YES.</p>
<p>The next example illustrates how to use pyobjus literals, and what their
Objective C equivalents are:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pyobjus</span> <span class="k">import</span> <span class="o">*</span>

<span class="c1"># The following examples demonstrate the pyobjus literals feature</span>
<span class="c1"># The first line denotes native objective c literals, and the second pyobjus literals</span>
<span class="c1"># SOURCE: http://clang.llvm.org/docs/ObjectiveCLiterals.html</span>

<span class="c1"># NSNumber *theLetterZ = @'Z';          // equivalent to [NSNumber numberWithChar:'Z']</span>
<span class="n">objc_c</span><span class="p">(</span><span class="s1">'Z'</span><span class="p">)</span>

<span class="c1"># NSNumber *fortyTwo = @42;             // equivalent to [NSNumber numberWithInt:42]</span>
<span class="n">objc_i</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span>

<span class="c1"># NSNumber *fortyTwoUnsigned = @42U;    // equivalent to [NSNumber numberWithUnsignedInt:42U]</span>
<span class="n">objc_ui</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span>

<span class="c1"># NSNumber *fortyTwoLong = @42L;        // equivalent to [NSNumber numberWithLong:42L]</span>
<span class="n">objc_l</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span>

<span class="c1"># NSNumber *fortyTwoLongLong = @42LL;   // equivalent to [NSNumber numberWithLongLong:42LL]</span>
<span class="n">objc_ll</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span>

<span class="c1"># NSNumber *piFloat = @3.141592654F;    // equivalent to [NSNumber numberWithFloat:3.141592654F]</span>
<span class="n">objc_f</span><span class="p">(</span><span class="mf">3.141592654</span><span class="p">)</span>

<span class="c1"># NSNumber *piDouble = @3.1415926535;   // equivalent to [NSNumber numberWithDouble:3.1415926535]</span>
<span class="n">objc_d</span><span class="p">(</span><span class="mf">3.1415926535</span><span class="p">)</span>

<span class="c1"># NSNumber *yesNumber = @YES;           // equivalent to [NSNumber numberWithBool:YES]</span>
<span class="n">objc_b</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>

<span class="c1"># NSNumber *noNumber = @NO;             // equivalent to [NSNumber numberWithBool:NO]</span>
<span class="n">objc_b</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>

<span class="c1"># NSArray *array = @[ @"Hello", NSApp, [NSNumber numberWithInt:42] ];</span>
<span class="n">objc_arr</span><span class="p">(</span><span class="n">objc_str</span><span class="p">(</span><span class="s1">'Hello'</span><span class="p">),</span> <span class="n">objc_str</span><span class="p">(</span><span class="s1">'some str'</span><span class="p">),</span> <span class="n">objc_i</span><span class="p">(</span><span class="mi">42</span><span class="p">))</span>

<span class="c1"># NSDictionary *dictionary = @{</span>
<span class="c1">#    @"name" : NSUserName(),</span>
<span class="c1">#    @"date" : [NSDate date],</span>
<span class="c1">#    @"processInfo" : [NSProcessInfo processInfo]</span>
<span class="c1"># };</span>
<span class="n">objc_dict</span><span class="p">({</span>
    <span class="s1">'name'</span><span class="p">:</span> <span class="n">objc_str</span><span class="p">(</span><span class="s1">'User name'</span><span class="p">),</span>
    <span class="s1">'date'</span><span class="p">:</span> <span class="n">autoclass</span><span class="p">(</span><span class="s1">'NSDate'</span><span class="p">)</span><span class="o">.</span><span class="n">date</span><span class="p">(),</span>
    <span class="s1">'processInfo'</span><span class="p">:</span> <span class="n">autoclass</span><span class="p">(</span><span class="s1">'NSProcessInfo'</span><span class="p">)</span><span class="o">.</span><span class="n">processInfo</span><span class="p">()</span>
<span class="p">})</span>

<span class="c1"># NSString *string = @"some string";</span>
<span class="n">objc_str</span><span class="p">(</span><span class="s1">'some string'</span><span class="p">)</span>
</pre></div>
</div>
<p>We have tried to make the build names for these literals clear and intuitive.
We start with the prefix <code class="docutils literal notranslate"><span class="pre">objc_</span></code> followed by the letter/letters which denote
the Objective C type.  For example, i for <code class="docutils literal notranslate"><span class="pre">int</span></code>, f for <code class="docutils literal notranslate"><span class="pre">float</span></code>, arr for
<code class="docutils literal notranslate"><span class="pre">NSArray</span></code>, dict for <code class="docutils literal notranslate"><span class="pre">NSDictionary</span></code>, etc…</p>
</div>
<div class="section" id="unknown-types">
<h2>Unknown types<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#unknown-types" title="Permalink to this headline">¶</a></h2>
<p>Let’s say that we have defined the following structures in our ObjcClass.</p>
<p>Note that we haven’t specified a type name for the structs, so their types
will be missing from any method signatures which use them:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">typedef</span> <span class="n">struct</span> <span class="p">{</span>
    <span class="nb">float</span> <span class="n">a</span><span class="p">;</span>
    <span class="nb">int</span> <span class="n">b</span><span class="p">;</span>
    <span class="n">NSRect</span> <span class="n">rect</span><span class="p">;</span>
<span class="p">}</span> <span class="n">unknown_str_new</span><span class="p">;</span>

<span class="n">typedef</span> <span class="n">struct</span> <span class="p">{</span>
    <span class="nb">int</span> <span class="n">a</span><span class="p">;</span>
    <span class="nb">int</span> <span class="n">b</span><span class="p">;</span>
    <span class="n">NSRect</span> <span class="n">rect</span><span class="p">;</span>
    <span class="n">unknown_str_new</span> <span class="n">u_str</span><span class="p">;</span>
<span class="p">}</span> <span class="n">unknown_str</span><span class="p">;</span>
</pre></div>
</div>
<p>Let’s play. Suppose that we have defined the following Objective C methods:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span> <span class="p">(</span><span class="n">unknown_str</span><span class="p">)</span> <span class="n">makeUnknownStr</span> <span class="p">{</span>
    <span class="n">unknown_str</span> <span class="nb">str</span><span class="p">;</span>
    <span class="nb">str</span><span class="o">.</span><span class="n">a</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
    <span class="nb">str</span><span class="o">.</span><span class="n">rect</span> <span class="o">=</span> <span class="n">NSMakeRect</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">50</span><span class="p">);</span>
    <span class="nb">str</span><span class="o">.</span><span class="n">u_str</span><span class="o">.</span><span class="n">a</span> <span class="o">=</span> <span class="mf">2.0</span><span class="p">;</span>
    <span class="nb">str</span><span class="o">.</span><span class="n">u_str</span><span class="o">.</span><span class="n">b</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>
    <span class="k">return</span> <span class="nb">str</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The purpose of this method is to create an unknown type struct and add some
values to it’s members. If you look at the debug logs from pyobjus, you will
notice that the method returns the following type:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>{?=ii{CGRect={CGPoint=dd}{CGSize=dd}}{?=fi{CGRect={CGPoint=dd}{CGSize=dd}}}}
</pre></div>
</div>
<p>From this we can see that method returns some type which contains two
integers and two structs. One struct is a <code class="docutils literal notranslate"><span class="pre">CGRect</span></code>, and another is some
unknown type which contains a float, an integer and a <code class="docutils literal notranslate"><span class="pre">CGRect</span></code> struct.
So, if the user hasn’t defined this struct, pyobjus can generate the type for
them. Let’s call this function:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ret_type</span> <span class="o">=</span> <span class="n">o_cls</span><span class="o">.</span><span class="n">makeUnknownStr</span><span class="p">()</span>
</pre></div>
</div>
<p>But wait, how will pyobjus know about the field names in the struct, because
from the method signature we see only types, not actual names? Well, pyobjus
will generate some ‘random’ names in alphabetical order.</p>
<p>In our case, the first member will have the name ‘a’, the second the name ‘b’
and the third the name <code class="docutils literal notranslate"><span class="pre">CGRect</span></code>. <code class="docutils literal notranslate"><span class="pre">CGRect</span></code> is used because it can help the
user as an indicator of actual type if it is missing. The last one is another
unknown type, so pyobjus will generate the name ‘c’.</p>
<p>Notice that in the case of the <code class="docutils literal notranslate"><span class="pre">CGRect</span></code>, it will have <code class="docutils literal notranslate"><span class="pre">origin</span></code> and <code class="docutils literal notranslate"><span class="pre">size</span></code>
members because it is already defined so we know about these. This is not true
for the last member, and pyobjus will thus choose the next alphabetical name
for this member.</p>
<p>Perhaps you are asking yourself how you would know what the actual generated
name is? Pyobjus will help you with this. There is a <code class="docutils literal notranslate"><span class="pre">getMembers</span></code> function
which returns the name and types of some of the fields in the struct:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">ret_type</span><span class="o">.</span><span class="n">getMembers</span><span class="p">()</span>
</pre></div>
</div>
<p>Python will output:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>&gt;&gt;&gt; [('a', &lt;class 'ctypes.c_int'&gt;), ('b', &lt;class 'ctypes.c_int'&gt;), ('CGRect', &lt;class 'pyobjus.objc_py_types.NSRect'&gt;), ('c', &lt;class 'pyobjus.objc_py_types.UnknownType'&gt;)]
</pre></div>
</div>
<p>If you want to provide your field names, you can do it this way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ret_type</span> <span class="o">=</span> <span class="n">o_cls</span><span class="o">.</span><span class="n">makeUnknownStr</span><span class="p">(</span><span class="n">members</span><span class="o">=</span><span class="p">[</span><span class="s1">'first'</span><span class="p">,</span> <span class="s1">'second'</span><span class="p">,</span> <span class="s1">'struct_field'</span><span class="p">,</span> <span class="s1">'tmp_field'</span><span class="p">])</span>
</pre></div>
</div>
<p>And if we now run the <code class="docutils literal notranslate"><span class="pre">getMembers</span></code> command, it will return this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>[('first', &lt;class 'ctypes.c_int'&gt;), ('second', &lt;class 'ctypes.c_int'&gt;), ('struct_field', &lt;class 'pyobjus.objc_py_types.NSRect'&gt;), ('tmp_field', &lt;class 'pyobjus.objc_py_types.UnknownType'&gt;)]
</pre></div>
</div>
<p>If you don’t need types, only names, you can call method in following way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">ret_type</span><span class="o">.</span><span class="n">getMembers</span><span class="p">(</span><span class="n">only_fields</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p>Python will output:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="p">[</span><span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">,</span> <span class="s1">'CGRect'</span><span class="p">,</span> <span class="s1">'c'</span><span class="p">]</span>
</pre></div>
</div>
<p>Also, if you want to know only names, you can do that the following way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">ret_type</span><span class="o">.</span><span class="n">getMembers</span><span class="p">(</span><span class="n">only_types</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p>Python will output:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>&gt;&gt;&gt; [&lt;class 'ctypes.c_int'&gt;, &lt;class 'ctypes.c_int'&gt;, &lt;class 'pyobjus.objc_py_types.NSRect'&gt;, &lt;class 'pyobjus.objc_py_types.UnknownType'&gt;]
</pre></div>
</div>
<p>If you want to use the returned type to pass it as an argument to some function,
there might be some problems. Pyobjus uses ctypes structures, so we can get the
actual pointer to the C structure from Python objects, but if we want to get
the correct values of the passed arg, we need to cast the pointer to the
appropriate type.</p>
<p>If the type is defined in <code class="docutils literal notranslate"><span class="pre">pyobjus/objc_cy_types.pxi</span></code>, pyobjus will convert it
for us, but if it isn’t, we will need to convert it manually. For example,
inside any Objective C methods where we are passing the struct value. Lets see
an example of this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span> <span class="p">(</span><span class="n">void</span><span class="p">)</span> <span class="n">useUnknownStr</span><span class="p">:(</span><span class="n">void</span><span class="o">*</span><span class="p">)</span><span class="n">str_vp</span> <span class="p">{</span>
    <span class="n">unknown_str</span> <span class="o">*</span><span class="n">str_p</span> <span class="o">=</span> <span class="p">(</span><span class="n">unknown_str</span><span class="o">*</span><span class="p">)</span><span class="n">str_vp</span><span class="p">;</span>
    <span class="n">unknown_str</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">str_p</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
    <span class="n">printf</span><span class="p">(</span><span class="s2">"</span><span class="si">%f</span><span class="se">\n</span><span class="s2">"</span><span class="p">,</span> <span class="nb">str</span><span class="o">.</span><span class="n">rect</span><span class="o">.</span><span class="n">origin</span><span class="o">.</span><span class="n">x</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>And from Python:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">o_cls</span><span class="o">.</span><span class="n">useUnknownStr_</span><span class="p">(</span><span class="n">ret_type</span><span class="p">)</span>
</pre></div>
</div>
<p>And Python will output with:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="mf">20.00</span>
</pre></div>
</div>
</div>
<div class="section" id="using-class">
<h2>Using class<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-class" title="Permalink to this headline">¶</a></h2>
<p>As you know, <code class="docutils literal notranslate"><span class="pre">class</span></code> is a Python keyword, so that might be a problem.</p>
<p>Let’s say that we want to get the Class type for an <code class="docutils literal notranslate"><span class="pre">NSString</span></code> instance…</p>
<p>We can use following:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">NSString</span> <span class="o">=</span> <span class="n">autoclass</span><span class="p">(</span><span class="s1">'NSString'</span><span class="p">)</span>
<span class="n">text</span> <span class="o">=</span> <span class="n">NSString</span><span class="o">.</span><span class="n">alloc</span><span class="p">()</span><span class="o">.</span><span class="n">init</span><span class="p">()</span>
<span class="n">text</span><span class="o">.</span><span class="n">oclass</span><span class="p">()</span>
</pre></div>
</div>
<p>This will return:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;</span><span class="n">pyobjus</span><span class="o">.</span><span class="n">ObjcClass</span> <span class="nb">object</span> <span class="n">at</span> <span class="mh">0x1057361b0</span><span class="o">&gt;</span>
</pre></div>
</div>
<p>So, now we can use the isKindOfClass: method:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">text</span><span class="o">.</span><span class="n">isKindOfClass_</span><span class="p">(</span><span class="n">NSString</span><span class="p">)</span>
</pre></div>
</div>
<p>This will output <code class="docutils literal notranslate"><span class="pre">True</span></code>. Let’s see another example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">NSArray</span> <span class="o">=</span> <span class="n">autoclass</span><span class="p">(</span><span class="s1">'NSArray'</span><span class="p">)</span>
<span class="n">text</span><span class="o">.</span><span class="n">isKindOfClass_</span><span class="p">(</span><span class="n">NSArray</span><span class="p">)</span>
</pre></div>
</div>
<p>And this will output <code class="docutils literal notranslate"><span class="pre">False</span></code>.</p>
<p>So, as you can see, if you want to use <code class="docutils literal notranslate"><span class="pre">class</span></code> with pyobjus, you will need to
use the <code class="docutils literal notranslate"><span class="pre">some_object.oclass()</span></code> method.</p>
</div>
<div class="section" id="using-selector">
<h2>Using @selector<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-selector" title="Permalink to this headline">¶</a></h2>
<p>There may be situations when you need to use <code class="docutils literal notranslate"><span class="pre">@selector</span></code>, which is an
Objective C feature. With pyobjus you can also get the SEL type for a method.
Let’s say that we want to get the SEL for the init method:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pyobjus</span> <span class="k">import</span> <span class="n">selector</span>
<span class="n">selector</span><span class="p">(</span><span class="s1">'init'</span><span class="p">)</span>
</pre></div>
</div>
<p>This will output:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;</span><span class="n">pyobjus</span><span class="o">.</span><span class="n">ObjcSelector</span> <span class="nb">object</span> <span class="n">at</span> <span class="mh">0x1057361c8</span><span class="o">&gt;</span>
</pre></div>
</div>
<p>So, instead of using <code class="docutils literal notranslate"><span class="pre">@selector(init)</span></code> with Objective C, you can use
<code class="docutils literal notranslate"><span class="pre">selector('init')</span></code> with pyobjus and Python to get the SEL type for that
method (in this case the ‘init’ method).</p>
<p>If you want get the SEL for <code class="docutils literal notranslate"><span class="pre">initWithUTF8String:</span></code> you can use:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">selector</span><span class="p">(</span><span class="s1">'initWithUTF8String:'</span><span class="p">)</span>
</pre></div>
</div>
<p>Other cases are the same for all methods.</p>
</div>
<div class="section" id="using-protocol">
<h2>Using @protocol<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-protocol" title="Permalink to this headline">¶</a></h2>
<p>Objective C protocols provide what other languages call interfaces. They specify
a list of methods which should be implemented in order to support that protocol.</p>
<p>Protocols define the interface which is then usually implemented by a delegate.
Pyobjus provides us with the protocol decorator to handle this, enabling
us to use Python objects as delegates:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@protocol</span><span class="p">(</span><span class="s1">'&lt;protocol_name&gt;'</span><span class="p">)</span>
</pre></div>
</div>
<p>Pyobjus will firstly try to use runtime introspection to determine the protocol
methods. If this fails, it will revert to the list of protocols contained in
the <cite>pyobjus/protocols.py</cite> file in your pyobjus checkout folder. Of course,
many libraries define their own protocols, so cannot be included by default.
For a complete list of protocols available on you system, run the
<cite>tools/build_protocols.py</cite> file and then rebuild pyobjus (as per the install).</p>
<p>So, how do we use this decorator? We add functions with names that correspond
to the protocol method names, then decorate these functions with the required
protocol:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@protocol</span><span class="p">(</span><span class="s1">'NSURLConnectionDelegate'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">connection_didFailWithError_</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">connection</span><span class="p">,</span> <span class="n">error</span><span class="p">):</span>
</pre></div>
</div>
<p>Here, we specify that our object method <cite>connection_didFailWithError_</cite> handles
the <cite>connection:didFailWithError:</cite> delegation  of the <cite>NSURLConnectionDelegate</cite>
protocol. Pyobjus then redirects this Objective-C message to our method.</p>
<p>For a complete example, please see the <cite>examples/delegate.py</cite> file.</p>
</div>
<div class="section" id="using-enum-types">
<h2>Using enum types<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-enum-types" title="Permalink to this headline">¶</a></h2>
<p>Pyobjus currently supports <code class="docutils literal notranslate"><span class="pre">NSComparisonResult</span></code> and <code class="docutils literal notranslate"><span class="pre">NSStringEncoding</span></code>
enums. If you want to use any others, you need to expand pyobjus with additional
types by adding then to the <code class="docutils literal notranslate"><span class="pre">pyobjus/objc_py_types.py</span></code> file.</p>
<p>But, let’s first see how to use the supported enum types with pyobjus. Consider
the following example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pyobjus</span> <span class="k">import</span> <span class="n">autoclass</span><span class="p">,</span> <span class="n">objc_str</span>
<span class="kn">from</span> <span class="nn">pyobjus.objc_py_types</span> <span class="k">import</span> <span class="n">NSComparisonResult</span>

<span class="k">def</span> <span class="nf">enum_example</span><span class="p">():</span>
    <span class="n">text</span> <span class="o">=</span> <span class="n">objc_str</span><span class="p">(</span><span class="s1">'some text'</span><span class="p">)</span>
    <span class="n">text_to_compare</span> <span class="o">=</span> <span class="n">objc_str</span><span class="p">(</span><span class="s1">'some text'</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">text</span><span class="o">.</span><span class="n">compare_</span><span class="p">(</span><span class="n">text_to_compare</span><span class="p">)</span> <span class="o">==</span> <span class="n">NSComparisonResult</span><span class="o">.</span><span class="n">NSOrderedSame</span><span class="p">:</span>
        <span class="nb">print</span> <span class="s1">'the same strings'</span>

    <span class="n">text_to_compare</span> <span class="o">=</span> <span class="n">objc_str</span><span class="p">(</span><span class="s1">'text'</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">text</span><span class="o">.</span><span class="n">compare_</span><span class="p">(</span><span class="n">text_to_compare</span><span class="p">)</span> <span class="o">==</span> <span class="n">NSComparisonResult</span><span class="o">.</span><span class="n">NSOrderedAscending</span><span class="p">:</span>
        <span class="nb">print</span> <span class="s1">'NSOrderedAscending strings'</span>

<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
    <span class="n">enum_example</span><span class="p">()</span>
</pre></div>
</div>
<p>You can see that we use the <code class="docutils literal notranslate"><span class="pre">NSComparisonResult</span></code> enum in the above example to
compare two strings. The Enum is defined in this way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">NSComparisonResult</span> <span class="o">=</span> <span class="n">enum</span><span class="p">(</span><span class="s2">"NSComparisonResult"</span><span class="p">,</span> <span class="n">NSOrderedAscending</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">NSOrderedSame</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">NSOrderedDescending</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
<p>The first argument of the <code class="docutils literal notranslate"><span class="pre">enum</span></code> function is the name of new enum type, and
the rest of the arguments are the field declarations of that enum. As you can
see it is pretty simple to declare enum’s with pyobjus, so you can add new enum
types to pyobjus. Keep in mind you will bo re-compile pyobjus is order to see
these changes in your Python environment.</p>
</div>
<div class="section" id="using-vararg-methods">
<h2>Using vararg methods<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-vararg-methods" title="Permalink to this headline">¶</a></h2>
<p>Objective C supports vararg (Variable Arguments) methods, so it would be great
if you could use vararg methods from pyobjus. Fortunately, you can.</p>
<p>Let’s we say that we want to use the <code class="docutils literal notranslate"><span class="pre">arrayWithObjects:</span></code> method, which is a
varargs method:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pyobjus</span> <span class="k">import</span> <span class="n">autoclass</span><span class="p">,</span> <span class="n">objc_str</span>

<span class="n">NSArray</span> <span class="o">=</span> <span class="n">autoclass</span><span class="p">(</span><span class="s1">'NSArray'</span><span class="p">)</span>
<span class="n">array</span> <span class="o">=</span> <span class="n">NSArray</span><span class="o">.</span><span class="n">arrayWithObjects_</span><span class="p">(</span><span class="n">objc_str</span><span class="p">(</span><span class="s1">'first string'</span><span class="p">),</span> <span class="n">objc_str</span><span class="p">(</span><span class="s1">'second string'</span><span class="p">),</span> <span class="kc">None</span><span class="p">)</span>

<span class="n">text</span> <span class="o">=</span> <span class="n">array</span><span class="o">.</span><span class="n">objectAtIndex_</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">text</span><span class="o">.</span><span class="n">UTF8String</span><span class="p">()</span>
</pre></div>
</div>
<p>Note that the last argument of a varargs methods must be <code class="docutils literal notranslate"><span class="pre">None</span></code>.</p>
</div>
<div class="section" id="using-c-array">
<h2>Using C array<a class="headerlink" href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html#using-c-array" title="Permalink to this headline">¶</a></h2>
<p>In this section we will explain how to use a C array from pyobjus.</p>
<p>Let’s say that we made a library <code class="docutils literal notranslate"><span class="pre">CArrayTestlib.dylib</span></code> which contains test
functions for a C array. Let’s load it:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">ctypes</span>
<span class="kn">from</span> <span class="nn">pyobjus</span> <span class="k">import</span> <span class="n">autoclass</span><span class="p">,</span> <span class="n">selector</span><span class="p">,</span> <span class="n">dereference</span><span class="p">,</span> <span class="n">CArray</span><span class="p">,</span> <span class="n">CArrayCount</span>
<span class="kn">from</span> <span class="nn">pyobjus.dylib_manager</span> <span class="k">import</span> <span class="n">load_dylib</span>

<span class="n">load_dylib</span><span class="p">(</span><span class="s1">'CArrayTestlib.dylib'</span><span class="p">,</span> <span class="n">usr_path</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">CArrayTestlib</span> <span class="o">=</span> <span class="n">autoclass</span><span class="p">(</span><span class="s2">"CArrayTestlib"</span><span class="p">)</span>
<span class="n">_instance</span> <span class="o">=</span> <span class="n">CArrayTestlib</span><span class="o">.</span><span class="n">alloc</span><span class="p">()</span>
</pre></div>
</div>
<p>Now we can call the <code class="docutils literal notranslate"><span class="pre">setIntValues:</span></code> method:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span> <span class="p">(</span><span class="n">void</span><span class="p">)</span> <span class="n">setIntValues</span><span class="p">:(</span><span class="nb">int</span><span class="p">[</span><span class="mi">10</span><span class="p">])</span><span class="n">val_arr</span>
<span class="p">{</span>
    <span class="n">NSLog</span><span class="p">(</span><span class="o">@</span><span class="s2">"Setting int array values..."</span><span class="p">);</span>
    <span class="n">memcpy</span><span class="p">(</span><span class="bp">self</span><span class="o">-&gt;</span><span class="n">values</span><span class="p">,</span> <span class="n">val_arr</span><span class="p">,</span> <span class="n">sizeof</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span> <span class="o">*</span> <span class="mi">10</span><span class="p">);</span>
    <span class="n">NSLog</span><span class="p">(</span><span class="o">@</span><span class="s2">"Values copied..."</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>in this way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">nums</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
<span class="n">array</span> <span class="o">=</span> <span class="p">(</span><span class="n">ctypes</span><span class="o">.</span><span class="n">c_int</span> <span class="o">*</span> <span class="mi">10</span><span class="p">)(</span><span class="o">*</span><span class="n">nums</span><span class="p">)</span>
<span class="n">_instance</span><span class="o">.</span><span class="n">setIntValues_</span><span class="p">(</span><span class="n">array</span><span class="p">)</span>
</pre></div>
</div>
<p>We can also return array values from this function:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>- (int*) getIntValues
{
    if (!self-&gt;values)
    {
        NSLog(@"Values have not been set.");
        return NULL;
    }
    else
        return self-&gt;values;
}
</pre></div>
</div>
<p>and consume them this way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">returned_PyList</span> <span class="o">=</span> <span class="n">dereference</span><span class="p">(</span><span class="n">_instance</span><span class="o">.</span><span class="n">getIntValues</span><span class="p">(),</span> <span class="n">of_type</span><span class="o">=</span><span class="n">CArray</span><span class="p">,</span> <span class="n">return_count</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">returned_PyList</span>
</pre></div>
</div>
<p>Note that here we passing a <code class="docutils literal notranslate"><span class="pre">return_count</span></code> optional argument, which holds the
number of array items which are returned from the <code class="docutils literal notranslate"><span class="pre">getIntValues</span></code> method.</p>
<p>But what if we don’t know the array count? In that case we need to have some
argument in which the method will put the array count value.</p>
<p>Consider following method:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>- (int*) getIntValuesWithCount:(unsigned int*) n
{
    NSLog(@" ... ... [+] getIntValuesWithCount(n=%zd)", n);
    NSLog(@" ... ... [+] *n=%zd", *n);
    if (!self-&gt;values)
    {
        NSLog(@"Values have not been set");
        return NULL;
    }
    else
    {
        *n = 10;
        NSLog(@" ... ... [+] getIntValuesWithCount(n=%zd)", n);
        NSLog(@" ... ... [+] *n=%zd", *n);
        return self-&gt;values;
    }
}
</pre></div>
</div>
<p>The first argument of this function will contain the array count when the return
statement is reached. So let’s call it:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">returned_PyList_withCount</span> <span class="o">=</span> <span class="n">dereference</span><span class="p">(</span><span class="n">_instance</span><span class="o">.</span><span class="n">getIntValuesWithCount_</span><span class="p">(</span><span class="n">CArrayCount</span><span class="p">),</span> <span class="n">of_type</span><span class="o">=</span><span class="n">CArray</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">returned_PyList_withCount</span>
</pre></div>
</div>
<p>Pyobjus will internally read from that argument and convert the returned C array
into a python list.</p>
<p>If the method returns values/an array count over reference or you don’t provide
<code class="docutils literal notranslate"><span class="pre">CArrayCount</span></code> in the right position in the method signature, you will get an
<code class="docutils literal notranslate"><span class="pre">IndexError:</span> <span class="pre">tuple</span> <span class="pre">index</span> <span class="pre">out</span> <span class="pre">of</span> <span class="pre">range</span></code> or segmentation fault, so don’t forget
to provide <code class="docutils literal notranslate"><span class="pre">CArrayCount</span></code> in the right position.</p>
<p>You may wonder, can you use multidimensional arrays from pyobjus? Yes, you can.
Consider following method:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>- (void) set2DIntValues: (int[10][10]) val_arr
{
    NSLog(@"Setting 2D int array values...");
    memcpy(self-&gt;int_2d_arr, val_arr, sizeof(int) * 10 * 10);
    NSLog(@"Values copied...");
}
- (int*) get2DIntValues
{
    if (!self-&gt;int_2d_arr)
    {
        NSLog(@"Values have not been set for int 2d array.");
        return NULL;
    }
    else
    {
        return (int*)self-&gt;int_2d_arr;
    }
}
</pre></div>
</div>
<p>To call this method first we need to make a multidimensional array from python
using nested lists:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">twoD_array</span> <span class="o">=</span> <span class="p">[</span>
    <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">11</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">14</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="mi">18</span><span class="p">,</span> <span class="mi">19</span><span class="p">,</span> <span class="mi">20</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">21</span><span class="p">,</span> <span class="mi">22</span><span class="p">,</span> <span class="mi">23</span><span class="p">,</span> <span class="mi">24</span><span class="p">,</span> <span class="mi">25</span><span class="p">,</span> <span class="mi">26</span><span class="p">,</span> <span class="mi">27</span><span class="p">,</span> <span class="mi">28</span><span class="p">,</span> <span class="mi">29</span><span class="p">,</span> <span class="mi">30</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">31</span><span class="p">,</span> <span class="mi">32</span><span class="p">,</span> <span class="mi">33</span><span class="p">,</span> <span class="mi">34</span><span class="p">,</span> <span class="mi">35</span><span class="p">,</span> <span class="mi">36</span><span class="p">,</span> <span class="mi">37</span><span class="p">,</span> <span class="mi">38</span><span class="p">,</span> <span class="mi">39</span><span class="p">,</span> <span class="mi">40</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">41</span><span class="p">,</span> <span class="mi">42</span><span class="p">,</span> <span class="mi">43</span><span class="p">,</span> <span class="mi">44</span><span class="p">,</span> <span class="mi">45</span><span class="p">,</span> <span class="mi">46</span><span class="p">,</span> <span class="mi">47</span><span class="p">,</span> <span class="mi">48</span><span class="p">,</span> <span class="mi">49</span><span class="p">,</span> <span class="mi">50</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">51</span><span class="p">,</span> <span class="mi">52</span><span class="p">,</span> <span class="mi">53</span><span class="p">,</span> <span class="mi">54</span><span class="p">,</span> <span class="mi">55</span><span class="p">,</span> <span class="mi">56</span><span class="p">,</span> <span class="mi">57</span><span class="p">,</span> <span class="mi">58</span><span class="p">,</span> <span class="mi">59</span><span class="p">,</span> <span class="mi">60</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">61</span><span class="p">,</span> <span class="mi">62</span><span class="p">,</span> <span class="mi">63</span><span class="p">,</span> <span class="mi">64</span><span class="p">,</span> <span class="mi">65</span><span class="p">,</span> <span class="mi">66</span><span class="p">,</span> <span class="mi">67</span><span class="p">,</span> <span class="mi">68</span><span class="p">,</span> <span class="mi">69</span><span class="p">,</span> <span class="mi">70</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">71</span><span class="p">,</span> <span class="mi">72</span><span class="p">,</span> <span class="mi">73</span><span class="p">,</span> <span class="mi">74</span><span class="p">,</span> <span class="mi">75</span><span class="p">,</span> <span class="mi">76</span><span class="p">,</span> <span class="mi">77</span><span class="p">,</span> <span class="mi">78</span><span class="p">,</span> <span class="mi">79</span><span class="p">,</span> <span class="mi">80</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">81</span><span class="p">,</span> <span class="mi">82</span><span class="p">,</span> <span class="mi">83</span><span class="p">,</span> <span class="mi">84</span><span class="p">,</span> <span class="mi">85</span><span class="p">,</span> <span class="mi">86</span><span class="p">,</span> <span class="mi">87</span><span class="p">,</span> <span class="mi">88</span><span class="p">,</span> <span class="mi">89</span><span class="p">,</span> <span class="mi">90</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">91</span><span class="p">,</span> <span class="mi">92</span><span class="p">,</span> <span class="mi">93</span><span class="p">,</span> <span class="mi">94</span><span class="p">,</span> <span class="mi">95</span><span class="p">,</span> <span class="mi">96</span><span class="p">,</span> <span class="mi">97</span><span class="p">,</span> <span class="mi">98</span><span class="p">,</span> <span class="mi">99</span><span class="p">,</span> <span class="mi">100</span><span class="p">]</span>
<span class="p">]</span>
</pre></div>
</div>
<p>This represents an <code class="docutils literal notranslate"><span class="pre">int[10][10]</span></code> array, so let’s call the above method:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">_instance</span><span class="o">.</span><span class="n">set2DIntValues_</span><span class="p">(</span><span class="n">twoD_array</span><span class="p">)</span>
<span class="n">returned_2d_list</span> <span class="o">=</span> <span class="n">dereference</span><span class="p">(</span><span class="n">_instance</span><span class="o">.</span><span class="n">get2DIntValues</span><span class="p">(),</span> <span class="n">of_type</span><span class="o">=</span><span class="n">CArray</span><span class="p">,</span> <span class="n">partition</span><span class="o">=</span><span class="p">[</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">])</span>
<span class="nb">print</span> <span class="n">returned_2d_list</span>
</pre></div>
</div>
<p>Note the optional <code class="docutils literal notranslate"><span class="pre">partition</span></code> argument of the dereference function.
This argument contains the format of the C array, in this case <code class="docutils literal notranslate"><span class="pre">[10,</span> <span class="pre">10]</span></code>.</p>
<p>You can find additional examples on this <a class="reference external" href="https://github.com/ivpusic/pyobjus/blob/master/examples/using_carray.py">link</a>.</p>
</div>
</div>


           </div>
           
          </div>
          <footer>
  
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
      
        <a href="https://pyobjus.readthedocs.io/en/latest/foundation_eg.html" class="btn btn-neutral float-right" title="Foundation framework examples" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
      
      
        <a href="https://pyobjus.readthedocs.io/en/latest/pyobjus_internal.html" class="btn btn-neutral" title="How does Pyobjus work?" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
      
    </div>
  

  <hr><div><div id="rtd-yjt5ds3k" class="ethical-rtd"></div></div>

  <div role="contentinfo">
    <p>
        © Copyright 2012, Mathieu Virbel, Gabriel Pettier
      
        <span class="commit">
          Revision <code>9df65fff</code>.
        </span>
      

    </p>
  </div>
  Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org/">Read the Docs</a>. 

</footer>

        </div>
      </div>

    </section>

  </div>
  

  <div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
    <span class="rst-current-version" data-toggle="rst-current-version">
      <span class="fa fa-book"> Read the Docs</span>
      v: latest
      <span class="fa fa-caret-down"></span>
    </span>
    <div class="rst-other-versions"><!-- Inserted RTD Footer -->

<div class="injected">

  

      
      
      
      <dl>
        <dt>版本</dt>
        
         <strong> 
        <dd><a href="https://pyobjus.readthedocs.io/en/latest/core_tutorials.html">latest</a></dd>
         </strong> 
        
      </dl>
      
      

      
      
      <dl>
        <dt>下载</dt>
        
        <dd><a href="https://readthedocs.org/projects/pyobjus/downloads/pdf/latest/">PDF</a></dd>
        
        <dd><a href="https://readthedocs.org/projects/pyobjus/downloads/htmlzip/latest/">HTML</a></dd>
        
        <dd><a href="https://readthedocs.org/projects/pyobjus/downloads/epub/latest/">Epub</a></dd>
        
      </dl>
      
      

      
      <dl>
        <!-- These are kept as relative links for internal installs that are http -->
        <dt>On Read the Docs</dt>
        <dd>
          <a href="https://readthedocs.org/projects/pyobjus/">Project Home</a>
        </dd>
        <dd>
          <a href="https://readthedocs.org/projects/pyobjus/builds/">构建</a>
        </dd>
        <dd>
          <a href="https://readthedocs.org/projects/pyobjus/downloads/">下载</a>
        </dd>
      </dl>
      

      

      
      <dl>
        <dt>On GitHub</dt>
        <dd>
          <a href="https://github.com/kivy/pyobjus/blob/master/docs/source/core_tutorials.rst">View</a>
        </dd>
        
      </dl>
      
      

      
      <dl>
        <dt>搜索</dt>
        <dd>
          <div style="padding: 6px;">
            <form id="flyout-search-form" class="wy-form" target="_blank" action="https://readthedocs.org/projects/pyobjus/search/" method="get">
              <input type="text" name="q" placeholder="Search docs">
              </form>
          </div>
        </dd>
      </dl>
      



      <hr>
      
        <small>
          <span>Hosted by <a href="https://readthedocs.org/">Read the Docs</a></span>
          <span> · </span>
          <a href="https://docs.readthedocs.io/page/privacy-policy.html">Privacy Policy</a>
        </small>
      

      

</div>
</div>
  </div>



  

    
    
      <script type="text/javascript">
          var DOCUMENTATION_OPTIONS = {
              URL_ROOT:'./',
              VERSION:'1.0a1',
              LANGUAGE:'en',
              COLLAPSE_INDEX:false,
              FILE_SUFFIX:'.html',
              HAS_SOURCE:  true,
              SOURCELINK_SUFFIX: '.txt'
          };
      </script>
        <script type="text/javascript" src="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/jquery-2.0.3.min.js"></script>
        <script type="text/javascript" src="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/jquery-migrate-1.2.1.min.js"></script>
        <script type="text/javascript" src="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/underscore.js"></script>
        <script type="text/javascript" src="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/doctools.js"></script>
        <script type="text/javascript" src="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/readthedocs-doc-embed.js"></script>
    

  

  <script type="text/javascript" src="./Pyobjus API tutorial — Pyobjus 1.0a1 documentation_files/theme.js"></script>

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script> 


<div id="rtd-bopdsri1"></div></body></html>